package com.yanqu.road.server.gameplayer.module.cricket.battle;

import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.cricket.helper.AddHpResult;
import com.yanqu.road.entity.cricket.helper.CricketFightForcePro;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.cricket.CricketProto;
import com.yanqu.road.server.gameplayer.module.cricket.CricketMgr;
import com.yanqu.road.server.gameplayer.module.cricket.model.*;
import com.yanqu.road.server.manger.config.SkillMgr;
import com.yanqu.road.server.manger.cricket.CricketAttRoundSkillMgr;
import com.yanqu.road.server.manger.cricket.CricketStartRoundSkillMgr;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;

public class CricketGame {
    public static CricketGame getInstance(CricketBattleData cricket, CricketBattleData cricket1) {
        return new CricketGame(cricket, cricket1);
    }

    private final CricketBattleData cricket;


    private final CricketBattleData cricket1;

    private final BattleData battleData;

    private final BattleData battleData1;


    private final AtomicLong maxBattleFrameId = new AtomicLong();


    private int maxRound;

    public CricketGame(CricketBattleData cricket, CricketBattleData cricket1) {
        this.cricket = cricket;
        this.cricket1 = cricket1;
        this.battleData = BattleData.getInstance(cricket);
        this.battleData1 = BattleData.getInstance(cricket1);

    }

    /**
     * 进行战斗
     *
     * @return
     */
    public CricketGameResult result() {
        CricketProto.CricketGameRound.Builder gameRoundBuilder = CricketProto.CricketGameRound.newBuilder();

        CricketGameResult cricketGameResult = CricketGameResult.getInstance();
        cricketGameResult.setCricketGameRoundBuilder(gameRoundBuilder);
        gameRoundBuilder.addCricket(this.cricket.getCricketMatchDataTemp());
        gameRoundBuilder.addCricket(this.cricket1.getCricketMatchDataTemp());

        gameRoundBuilder.addUserData(this.battleData.getBattleUserData(this.battleData1));
        gameRoundBuilder.addUserData(this.battleData1.getBattleUserData(this.battleData));
        try {
            for (int i = 0; i < GameConfig.CRICKET_FIGHT_ROUND_MAX; i++) {
                this.maxRound++;
                int maxPowerSide = this.getMaxPowerSide();
                BattleData actionUser = this.getActionUser(maxPowerSide);
                BattleData targetUser = this.getTargetUser(maxPowerSide);
                actionUser.decCoolingDownOnStartRound();
                targetUser.decCoolingDownOnStartRound();


                if (actionUser.getFreeze() > 0) {
                    actionUser.setFreeze(actionUser.getFreeze() - 1);
                    CricketProto.CricketAttackRound.Builder attackRound = CricketProto.CricketAttackRound.newBuilder();
                    attackRound.setUserId(actionUser.getUserId());
                    attackRound.setMaxPowerSide(maxPowerSide);
                    attackRound.setRoundId(this.maxRound);
                    attackRound.setFreeze(actionUser.getFreeze());
                    attackRound.setFreezeSkillId(actionUser.getFreezeSkillId());
                    gameRoundBuilder.addAttackRound(attackRound);
                } else {
                    CricketProto.CricketAttackRound.Builder attackRound = this.attackRound(actionUser, targetUser, this.maxRound, maxPowerSide);
                    gameRoundBuilder.addAttackRound(attackRound);
                    if (targetUser.isOver()) {
                        gameRoundBuilder.setWinUserId(actionUser.getUserId());
                        return cricketGameResult;
                    }
                    if (actionUser.isOver()) {
                        gameRoundBuilder.setWinUserId(targetUser.getUserId());
                        return cricketGameResult;
                    }
                }

                if (targetUser.getFreeze() > 0) {
                    targetUser.setFreeze(targetUser.getFreeze() - 1);
                    CricketProto.CricketAttackRound.Builder attackRound1 = CricketProto.CricketAttackRound.newBuilder();
                    attackRound1.setUserId(targetUser.getUserId());
                    attackRound1.setMaxPowerSide(maxPowerSide);
                    attackRound1.setRoundId(this.maxRound);
                    attackRound1.setFreeze(targetUser.getFreeze());
                    attackRound1.setFreezeSkillId(targetUser.getFreezeSkillId());
                    gameRoundBuilder.addAttackRound(attackRound1);
                } else {
                    CricketProto.CricketAttackRound.Builder attackRound1 = this.attackRound(targetUser, actionUser, this.maxRound, maxPowerSide);
                    gameRoundBuilder.addAttackRound(attackRound1);
                    if (actionUser.isOver()) {
                        gameRoundBuilder.setWinUserId(targetUser.getUserId());
                        return cricketGameResult;
                    }
                    if (targetUser.isOver()) {
                        gameRoundBuilder.setWinUserId(actionUser.getUserId());
                        return cricketGameResult;
                    }
                }

//                actionUser.checkCoolingDownOnEndRound();
//                targetUser.checkCoolingDownOnEndRound();

            }
        } finally {
            cricketGameResult.setBattleData(this.battleData);
            cricketGameResult.setBattleData1(this.battleData1);
            cricketGameResult.setMaxRound(this.maxRound);
            gameRoundBuilder.setMaxRound(this.maxRound);
        }


        if (this.battleData.getHp() > this.battleData1.getHp()) {
            gameRoundBuilder.setWinUserId(this.battleData.getUserId());
        } else {
            gameRoundBuilder.setWinUserId(this.battleData1.getUserId());
        }
        return cricketGameResult;
    }


    public CricketProto.CricketAttackRound.Builder attackRound(BattleData actionUser, BattleData targetUser, int roundId, int maxPowerSide) {
        CricketProto.CricketAttackRound.Builder attackRoundBuilder = CricketProto.CricketAttackRound.newBuilder();

        for (CricketProto.CricketBattleSkillDataTemp skillDataTemp : actionUser.getAllSkillDataMsgTemp()) {
            attackRoundBuilder.addBothSkillData(skillDataTemp);
        }
        for (CricketProto.CricketBattleSkillDataTemp skillDataTemp : targetUser.getAllSkillDataMsgTemp()) {
            attackRoundBuilder.addBothSkillData(skillDataTemp);
        }
        //【步骤1】回合前
        this.startRoundNew(actionUser, targetUser, roundId, attackRoundBuilder);

        attackRoundBuilder.setMaxPowerSide(maxPowerSide);
        attackRoundBuilder.setRoundId(roundId);
        attackRoundBuilder.setUserId(actionUser.getUserId());
        try {
            if (this.isOver(attackRoundBuilder, eCricketBattleRoundStep.StartRound.getValue(), 0)) {
                return attackRoundBuilder;
            }
            //【步骤2】攻击
            boolean isMiss = false;
            for (int i = 0; i < actionUser.getAttTime(); i++) {//遍历攻击次数
                SkillData attackRoundSkill = actionUser.getAttackRoundSkill();
                if (attackRoundSkill != null) {
                    isMiss = this.attackMiss(attackRoundSkill, targetUser);
                    //攻击
                    this.attack(actionUser, targetUser, attackRoundSkill, isMiss, attackRoundBuilder);
                    if (this.isOver(attackRoundBuilder, eCricketBattleRoundStep.AfterAttack.getValue(), 0)) {
                        return attackRoundBuilder;
                    }
                }
            }

            //【步骤3】回合结束前
            this.endRound(actionUser, targetUser, isMiss, attackRoundBuilder);
            if (this.isOver(attackRoundBuilder, eCricketBattleRoundStep.EndRound.getValue(), 0)) {
                return attackRoundBuilder;
            }

            //【步骤4】回合结束后
            List<CricketProto.CricketBattleFrame.Builder> afterRound = this.afterRound(actionUser, targetUser);
            for (CricketProto.CricketBattleFrame.Builder builder : afterRound) {
                attackRoundBuilder.addAfterAttack(builder);
            }
            if (this.isOver(attackRoundBuilder, eCricketBattleRoundStep.EndRound.getValue(), 0)) {
                return attackRoundBuilder;
            }
        } finally {
            attackRoundBuilder.addUserData(actionUser.getBattleUserData(targetUser));
            attackRoundBuilder.addUserData(targetUser.getBattleUserData(actionUser));
        }

        return attackRoundBuilder;
    }

    public boolean attackMiss(SkillData actionSkillData, BattleData target) {
        for (SkillData skillData : target.getSkillDataList()) {
            //{0}概率闪避敌方的快夹。
            if (skillData.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill142.getValue()) {
                if (actionSkillData.getSkillEffect().getP4() == skillData.getSkillEffect().getP2()) {
                    int i = this.rand1000();
                    if (i < skillData.getSkillEffect().getP1()) {
                        return true;
                    }
                }
            }
            //赵云-龙魂护卫：每次被攻击前，赵云获得{0}的闪避，加成可叠加。
            if (skillData.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill405.getValue()) {
                int i = this.rand1000();
                if (i < target.getParam()) {
//                    //闪避成功，闪避值清0
//                    target.setParam(0);
                    return true;
                }
            }
        }
        return false;
    }

    public BattleData getActionUser(int maxPowerSide) {
        if (maxPowerSide == 1) {
            return this.battleData1;
        }
        return battleData;
    }

    public BattleData getTargetUser(int maxPowerSide) {
        if (maxPowerSide == 1) {
            return this.battleData;
        }
        return battleData1;
    }

    /**
     * 回合前（优化版）
     * @param action
     * @param target
     * @param roundId
     * @param attackRoundBuilder
     */
    public void startRoundNew(BattleData action, BattleData target, int roundId, CricketProto.CricketAttackRound.Builder attackRoundBuilder) {
        //攻击对方前，对方技能
        for (SkillData skillData : target.getSkillDataList()) {
            boolean returnFlag = CricketStartRoundSkillMgr.targetSkillHandle(this, skillData, action, target, roundId, attackRoundBuilder);
            if (returnFlag) {
                return;
            }
        }
        //回合前技能，我方技能
        for (SkillData skillData : action.getSkillDataList()) {
            boolean returnFlag = CricketStartRoundSkillMgr.actionSkillHandle(this, skillData, action, target, roundId, attackRoundBuilder);
            if (returnFlag) {
                return;
            }
        }
    }

    /**
     * 攻击
     *
     * @param action
     * @param target
     * @return
     */
    public void attack(BattleData action, BattleData target, SkillData attackRoundSkill, boolean isMiss, CricketProto.CricketAttackRound.Builder attackRoundBuilder) {
        //【步骤1】攻击技能处理
        long baseAttack = action.getAttack(target);
        int attackTimes = attackRoundSkill.getSkillEffect().getP2();
        long attack = 0;
        long addPower = 0;
        long addHp = 0;
        if (attackRoundSkill.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill137.getValue()) {
            attack = BigDecimal.valueOf(baseAttack).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP1())).
                    divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).multiply(BigDecimal.valueOf(attackTimes)).longValue();
        } else if (attackRoundSkill.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill160.getValue()) {
            attack = BigDecimal.valueOf(baseAttack).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP1())).
                    multiply(BigDecimal.valueOf(attackTimes)).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
            addPower = BigDecimal.valueOf(action.getPower()).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP4())).
                    divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
        } else if (attackRoundSkill.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill161.getValue()) {
            attack = BigDecimal.valueOf(action.getPower()).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP1())).
                    multiply(BigDecimal.valueOf(attackTimes)).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
            addPower = BigDecimal.valueOf(action.getPower()).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP4())).
                    divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
        } else if (attackRoundSkill.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill162.getValue()) {
            attack = BigDecimal.valueOf(baseAttack).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP1())).
                    multiply(BigDecimal.valueOf(attackTimes)).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
            addHp = BigDecimal.valueOf(action.getMaxHp()).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP4())).
                    divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
        }
//        long perAttack = BigDecimal.valueOf(attack).divide(BigDecimal.valueOf(attackTimes), 8, RoundingMode.DOWN).longValue();

        //伤害减免
        int subAddition = 0;
        for (SkillData skillData : target.getSkillDataList()) {
            if(skillData.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill401.getValue()){
                subAddition += target.getParam();
                break;
            }
        }
        if(subAddition > 0 && subAddition <= 1000){
            attack = BigDecimal.valueOf(attack).multiply(BigDecimal.valueOf(1000 - subAddition)).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
        }

        CricketProto.CricketBattleFrame.Builder attackBattleFrameBuilder = this.newBattleFrameBuilder();
        attackBattleFrameBuilder.setActionUserId(action.getUserId());
        attackBattleFrameBuilder.setTargetUserId(target.getUserId());
        attackBattleFrameBuilder.setSkillId(attackRoundSkill.getSkillId());
        attackBattleFrameBuilder.setAttackTimes(attackTimes);
        AddHpResult baseAttReHpResult = null; //基础攻击miss的情况下，为null
        if (isMiss) {
            attackBattleFrameBuilder.setIsMiss(isMiss);
            this.fillRemainHp(attackBattleFrameBuilder);
            attackRoundBuilder.addAttack(attackBattleFrameBuilder);
        } else {
            baseAttReHpResult = target.addHp(-attack);
            attackBattleFrameBuilder.setAttack(baseAttReHpResult.getValue());
            attackBattleFrameBuilder.setIsKill(baseAttReHpResult.isKill());
            attackBattleFrameBuilder.setHarmEffectSkillId(baseAttReHpResult.getReduceHpEffectSkillId());
            attackBattleFrameBuilder.setIsMiss(baseAttReHpResult.isMissFlag());
            if (baseAttReHpResult.isMissFlag()) {
                this.fillRemainHp(attackBattleFrameBuilder);
                attackRoundBuilder.addAttack(attackBattleFrameBuilder);
            } else {
                if (attackRoundSkill.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill137.getValue() && attackRoundSkill.getSkillEffect().getP4() == 3) {//1快夹2冲夹3举摔
                    //摔举减少对方气势
                    long value = BigDecimal.valueOf(target.getPower()).multiply(BigDecimal.valueOf(attackRoundSkill.getSkillEffect().getP3())).
                            divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).longValue();
                    target.addPower(value);
                    attackBattleFrameBuilder.setAddPower(value);
                }
                if (addPower > 0) {
                    action.addPower(addPower);
                    attackBattleFrameBuilder.setAddPower(addPower);
                }
                this.fillRemainHp(attackBattleFrameBuilder);
                attackBattleFrameBuilder.setExt("0");
                attackRoundBuilder.addAttack(attackBattleFrameBuilder);
                //普通攻击的回血
                if (addHp > 0) {
                    CricketProto.CricketBattleFrame.Builder addHpFrameBuilder = this.newBattleFrameBuilder();
                    addHpFrameBuilder.setActionUserId(action.getUserId());
                    addHpFrameBuilder.setTargetUserId(action.getUserId());
                    addHpFrameBuilder.setSkillId(attackRoundSkill.getSkillId());
                    AddHpResult actionAddHpResult = action.addHp(addHp);
                    addHpFrameBuilder.setAttack(actionAddHpResult.getValue());
                    addHpFrameBuilder.setIsKill(actionAddHpResult.isKill());
                    addHpFrameBuilder.setExt("1");//用来区分同一个技能的伤害和恢复
                    this.fillRemainHp(addHpFrameBuilder);
                    attackRoundBuilder.addAttack(addHpFrameBuilder);
                }
                if (this.isOver(attackRoundBuilder, eCricketBattleRoundStep.Attack.getValue(), attackBattleFrameBuilder.getBattleFrameId())) {
                    return;
                }
            }
        }



        //【步骤2】攻击后，对方技能处理
        for (SkillData skillData : target.getSkillDataList()) {
            boolean returnFlag = CricketAttRoundSkillMgr.targetSkillHandle(this, skillData, attackRoundSkill, baseAttReHpResult, action, target, attackRoundBuilder, attackBattleFrameBuilder.getBattleFrameId());
            if (returnFlag) {
                return;
            }
        }

        //【步骤3】攻击后，我方技能处理
        for (SkillData skillData : action.getSkillDataList()) {
            boolean returnFlag = CricketAttRoundSkillMgr.actionSkillHandle(this, skillData, attackRoundSkill, baseAttReHpResult, action, target, attackRoundBuilder, attackBattleFrameBuilder.getBattleFrameId());
            if (returnFlag) {
                return;
            }
        }

    }


    /**
     * 回合结束
     *
     * @param action
     * @param target
     * @return
     */
    public void endRound(BattleData action, BattleData target, boolean isMiss, CricketProto.CricketAttackRound.Builder attackRoundBuilder) {
        for (SkillData skillData : action.getSkillDataList()) {
            if (skillData.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill152.getValue()) {
                skillData.effectAmountInc();
                CricketProto.CricketBattleFrame.Builder newBattleFrameBuilder = this.newBattleFrameBuilder();
                newBattleFrameBuilder.setActionUserId(action.getUserId());
                newBattleFrameBuilder.setTargetUserId(target.getUserId());
                newBattleFrameBuilder.setSkillId(skillData.getSkillId());
                BigDecimal multiply = BigDecimal.valueOf(target.getHp()).multiply(BigDecimal.valueOf(skillData.getSkillEffect().getP1()));
                long value = multiply.multiply(BigDecimal.valueOf(skillData.getOverlay())).divide(BigDecimal.valueOf(1000), 0, RoundingMode.DOWN).longValue();
                AddHpResult addHpResult = target.addHp(value);
                newBattleFrameBuilder.setAttack(addHpResult.getValue());
                newBattleFrameBuilder.setIsKill(addHpResult.isKill());
                newBattleFrameBuilder.setHarmEffectSkillId(addHpResult.getReduceHpEffectSkillId());
                newBattleFrameBuilder.setIsMiss(addHpResult.isMissFlag());
                //这个客户端需要，1代表烧的时候
                newBattleFrameBuilder.setExt("1");
                this.fillRemainHp(newBattleFrameBuilder);
                attackRoundBuilder.addEndRound(newBattleFrameBuilder);
                if (this.isOver(attackRoundBuilder, eCricketBattleRoundStep.EndRound.getValue(), newBattleFrameBuilder.getBattleFrameId())) {
                    return;
                }
            }

            if (skillData.getEffectRound() > 0) {
                skillData.setEffectRound(skillData.getEffectRound() - 1);
            }

        }

        boolean triggerGnash = this.triggerGnash(target, action);
        boolean triggerSurrender = this.triggerSurrender(target, action);
        if (!isMiss) {
            if (triggerGnash) {
                CricketProto.CricketBattleFrame.Builder newBattleFrameBuilder = this.newBattleFrameBuilder();
                newBattleFrameBuilder.setSkillId(0);
                newBattleFrameBuilder.setActionUserId(target.getUserId());
                newBattleFrameBuilder.setTargetUserId(target.getUserId());
                newBattleFrameBuilder.setTriggerGnash(true);
                if (triggerSurrender) {
                    newBattleFrameBuilder.setGnashFailed(true);
                    target.setSurrender(true);
                }
                this.fillRemainHp(newBattleFrameBuilder);
                attackRoundBuilder.addEndRound(newBattleFrameBuilder);
            }
        }

        //技能重置回合
        action.checkCoolingDownOnEndRound();
    }


    public List<CricketProto.CricketBattleFrame.Builder> afterRound(BattleData action, BattleData target) {
        List<CricketProto.CricketBattleFrame.Builder> list = new ArrayList<>();
        List<SkillData> skillDataList = target.getSkillDataList();
        for (SkillData skillData : skillDataList) {

        }

        action.roundAtdDecRound();

        //重置攻击次数
        action.setAttTime(1);

        return list;
    }


    public boolean isRandomHit(int rate) {
        int i = this.rand1000();
        if (rate < i) {
            return true;
        }
        return false;
    }


    public int rand1000() {
        Random random = new Random();
        int i = random.nextInt(1000);
        return i;
    }


    public CricketBattleData getCricket() {
        return cricket;
    }

    public CricketBattleData getCricket1() {
        return cricket1;
    }

    public BattleData getBattleData() {
        return battleData;
    }

    public BattleData getBattleData1() {
        return battleData1;
    }

    public int getMaxPowerSide() {
        if (this.battleData.getPower() == this.battleData1.getPower()) {
            Random random = new Random();
            int i = random.nextInt(2);
            return i;
        }
        if (this.battleData.getPower() < this.battleData1.getPower()) {
            return 1;
        }
        return 0;
    }

    public int getMaxRound() {
        return maxRound;
    }


    /**
     * 打牙，如果打牙的时候失败，则直接输了
     *
     * @param action
     * @return
     */
    public boolean triggerGnash(BattleData action, BattleData target) {
        if (action.getFightScareNum() <= 0) {
            return false;
        }
        if (action.getFightScareColdDown() > 0) {
            action.setFightScareColdDown(action.getFightScareColdDown() - 1);
            return false;
        }

        for (SkillData skillData : action.getSkillDataList()) {
            if (skillData.getSkillEffect().getSkillType() == eSkillType.CricketBattleSkill153.getValue()) {
                return false;
            }
        }

        CricketFightForcePro cricketFightForcePro = CricketMgr.getConfig().getCricketFightForcePro();
        long k1 = cricketFightForcePro.getK1();
        long k2 = cricketFightForcePro.getK2();
        long k3 = cricketFightForcePro.getK3();
        long k4 = cricketFightForcePro.getK4();

        long H1 = action.getMaxHp();
        long h1 = action.getHp();
        long a1 = action.getAttack(target);
        long q1 = action.getPower();

        long H2 = target.getMaxHp();
        long h2 = target.getHp();
        long a2 = target.getAttack(action);
        long q2 = target.getPower();

        BigDecimal step0 = BigDecimal.valueOf(k4).divide(BigDecimal.valueOf(1000), 8, RoundingMode.UP);
        BigDecimal step1 = BigDecimal.valueOf((H1 - h1)).divide(BigDecimal.valueOf(h1), 8, RoundingMode.UP);
        if (step0.compareTo(step1) < 0) {
            step1 = step0;
        }
        step1 = step1.multiply(BigDecimal.valueOf(k1));
        BigDecimal step2 = BigDecimal.valueOf(k2).divide(BigDecimal.valueOf(1000), 8, RoundingMode.UP);
        BigDecimal step3 = BigDecimal.valueOf(q2).divide(BigDecimal.valueOf(q1), 8, RoundingMode.UP);
        BigDecimal step4 = step2;
        if (step3.compareTo(step2) < 0) {
            step4 = step3;
        }
        double d_step5 = Math.pow(step4.doubleValue(), (double) k3 / (double) 1000);
        BigDecimal step5 = BigDecimal.valueOf(d_step5);
        step5 = step5.add(BigDecimal.valueOf(1));
        BigDecimal p = step1.multiply(step5);
        int r = p.intValue();
        int i = this.rand1000();

//        if (Config.isDebug()) {
//            String format = String.format("怯场概率计算  k1:%d,k2:%d,k3:%d,k4:%d, H1:%d,h1:%d,q1:%d,q2:%d, r:%d", k1, k2, k3, k4, H1, h1, q1, q2, r);
//            System.out.println(format);
//        }

        if (i < p.intValue()) {
            action.setFightScareColdDown(GameConfig.CRICKET_FIGHT_SCARE_CD);
            action.setTotalFightScareNum(action.getTotalFightScareNum() + 1);
            return true;
        }
        return false;
    }

    /**
     * 是否投降
     *
     * @param action
     * @param target
     * @return
     */
    private boolean triggerSurrender(BattleData action, BattleData target) {
        CricketFightForcePro cricketFightForcePro = CricketMgr.getConfig().getCricketFightForcePro();
        long n1 = cricketFightForcePro.getN1();
        long n2 = cricketFightForcePro.getN2();
        long n3 = cricketFightForcePro.getN3();

        long H1 = action.getMaxHp();
        long h1 = action.getHp();
        long a1 = action.getAttack(target);
        long q1 = action.getPower();

        long H2 = target.getMaxHp();
        long h2 = target.getHp();
        long a2 = target.getAttack(action);
        long q2 = target.getPower();


        BigDecimal step0 = BigDecimal.valueOf(n2).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN);

        BigDecimal step1 = BigDecimal.valueOf(q2).divide(BigDecimal.valueOf(q1), 8, RoundingMode.DOWN);

        if (step0.compareTo(step1) < 0) {
            step1 = step0;
        }

        double pow = Math.pow(step1.doubleValue(), (double) n3 / (double) 1000);
        step1 = BigDecimal.valueOf(pow).add(BigDecimal.valueOf(1)).multiply(BigDecimal.valueOf(n1));

        int r = step1.intValue();

//        if (Config.isDebug()) {
//            String format = String.format("投降概率计算  n1:%d,n2:%d,n3:%d, H1:%d,h1:%d,q1:%d,q2:%d, r:%d", n1, n2, n3, H1, h1, q1, q2, r);
//            System.out.println(format);
//        }
        int i = this.rand1000();
        if (i < r) {
            return true;
        }
        return false;
    }

    public CricketProto.CricketBattleFrame.Builder newBattleFrameBuilder() {
        CricketProto.CricketBattleFrame.Builder builder = CricketProto.CricketBattleFrame.newBuilder();
        long battleFrameId = this.maxBattleFrameId.incrementAndGet();
        builder.setBattleFrameId(battleFrameId);

        return builder;
    }

    /**
     * 是否有人挂了
     *
     * @return
     */
    public boolean isOver(CricketProto.CricketAttackRound.Builder attackRoundBuilder, int step, long lastFrameId) {
        if (this.battleData.isOver()) {
            BattleData battle = this.battleData;
            battle.checkReviveBySkill165(attackRoundBuilder, step, this, lastFrameId);
            if (this.battleData.isOver()) {
                return true;
            }
        }
        if (this.battleData1.isOver()) {
            BattleData battle = this.battleData1;
            battle.checkReviveBySkill165(attackRoundBuilder, step, this, lastFrameId);
            if (this.battleData1.isOver()) {
                return true;
            }
        }
        return false;
    }

    public void fillRemainHp(CricketProto.CricketBattleFrame.Builder builder) {
        builder.addBothRemainHp(battleData.getHp());
        builder.addBothRemainHp(battleData1.getHp());
        builder.addBothPower(battleData.getPower());
        builder.addBothPower(battleData1.getPower());
        builder.addBothAttack(battleData.getAttack(battleData1));
        builder.addBothAttack(battleData1.getAttack(battleData));
        builder.addBothMaxHp(battleData.getMaxHp());
        builder.addBothMaxHp(battleData1.getMaxHp());
        for (CricketProto.CricketBattleSkillDataTemp skillDataTemp : battleData.getAllSkillDataMsgTemp()) {
            builder.addBothSkillData(skillDataTemp);
        }
        for (CricketProto.CricketBattleSkillDataTemp skillDataTemp : battleData1.getAllSkillDataMsgTemp()) {
            builder.addBothSkillData(skillDataTemp);
        }
    }

}
